#include "control.h"

#include <QWidget>
#include <QDebug>

#include <stdlib.h>

#include "canvas.h"
#include "snake.h"
#include "winwidget.h"
#include "snakegame.h"

Control::Control(Canvas* c)
    : canvas(c)
{
    connect(&timer, SIGNAL(timeout()), this, SLOT(controlTime()));
    aboutWin = new AboutWindow(this);
    player.clear();
    player.append("Player 1");
    readSlotGames();
}

void Control::setup(int gx, int gy, int cl)
{
    grid_x = gx;
    grid_y = gy;
    cellLenght = cl;
}

void Control::start()
{
    srand ( time(NULL) );
    update = false;
    gameover = false;
    gamewin = false;
    pause = false;
    level = 1;
    scores = 0;
    timer.setInterval( (33-3*level)*1000/60);
    restartTime();
    player = "Player 1";
    game = new Game();
    game->setup(player, cellLenght, grid_x, grid_y);
    game->start();
    canvas->setSnake( game->getSnake() );
    canvas->setWall( game->getWall() );
    canvas->setDimensions(grid_x, grid_y);
    canvas->setPaused(pause);
    addEat();
}

void Control::setLabel(QLabel *l)
{
    label = l;
}

void Control::setPauseAct(QAction *act)
{
    pauseAct = act;
}

int Control::getCellLenght()
{
    return cellLenght;
}

void Control::addEat()
{
    eat = game->createEat();
    canvas->setEat( eat.x(), eat.y());
}

void Control::controlKey(int key)
{
    switch(key){
    case Qt::Key_Left:
        moveSnake( LEFT );
        break;
    case Qt::Key_Right:
        moveSnake( RIGHT );
        break;
    case Qt::Key_Up:
        moveSnake( UP );
        break;
    case Qt::Key_Down:
        moveSnake( DOWN );
        break;
    }
}

void Control::tooglePause()
{
    if(!gameover and !gamewin){
        pause = !pause;
        canvas->setPaused(pause);
        QString msg;
        msg.append(" Level: ");
        QString l;
        l.setNum(level);
        msg.append(l);
        msg.append("\tScores: ");
        l.setNum(scores);
        msg.append(l);
        if(pause){
            msg.append("\t\t(PAUSED)");
            pauseAct->setText("Resume");
        }
        else{
            pauseAct->setText("Pause");
        }
        label->setText(msg);
    }
}

void Control::about()
{
    tooglePause();
    aboutWin->show();
}

void Control::closeAllWindows()
{
    aboutWin->close();
}

void Control::controlTime()
{
    timer.stop();
    QPoint head = game->getSnakeHead();
    QPoint sneak = game->getSnakeBody()[game->getSnakeBody().size()-2];
    if(head.x() < sneak.x() and head.y() == sneak.y()){
        moveSnake(LEFT);
    }
    else if(head.x() > sneak.x() and head.y() == sneak.y()){
        moveSnake(RIGHT);
    }
    // y goes from up to down
    else if(head.x() == sneak.x() and head.y() < sneak.y()){
        moveSnake(UP);
    }
    else if(head.x() == sneak.x() and head.y() > sneak.y()){
        moveSnake(DOWN);
    }
    else{
        qDebug() << "\n\nWarning!!!\nMovement not valid.\n\n";
    }
    timer.start();
}

void Control::moveSnake(int mov)
{
    if(!gameover and !gamewin and !pause){
        Snake* snake = game->getSnake();
        QPoint head = snake->getHead();
        switch(mov){
        case LEFT:
            if(head.x() - (cellLenght+1) == eat.x() and head.y() == eat.y() ){
                gameover = snake->growLeft();
                addEat();
                update = true;
            }
            else{
                gameover = snake->moveLeft();
            }
            break;
        case RIGHT:
            if(head.x() + (cellLenght+1) == eat.x() and head.y() == eat.y() ){
                gameover = snake->growRight();
                addEat();
                update = true;
            }
            else{
                gameover = snake->moveRight();
            }
            break;
        case UP:
            if(head.x() == eat.x() and head.y() == eat.y() + (cellLenght+1)){
                gameover = snake->growUp();
                addEat();
                update = true;
            }
            else{
                gameover = snake->moveUp();
            }
            break;
        case DOWN:
            if(head.x() == eat.x() and head.y() == eat.y() - (cellLenght+1) ){
                gameover = snake->growDown();
                addEat();
                update = true;
            }
            else{
                gameover = snake->moveDown();
            }
            break;
        }
        canvas->updateGL();
        if(gameover){
            update = true;
        }
        if(update){
            int bs = snake->getBody().size()-3;
            if( bs > 0 and bs % 15 == 0){
                level++;
                scores += level*10;
                if (level > 3){
                    gamewin = true;
                    label->setText("Congratulations!!! You WIN!!!");
                    return;
                }
                timer.setInterval( (31-3*level)*1000/60 );
            }
            if(!gameover){
                scores += level;
            }
            QString msg;
            msg.append(" Level: ");
            QString l;
            l.setNum(level);
            msg.append(l);
            msg.append("\tScores: ");
            l.setNum(scores);
            msg.append(l);
            qDebug() << (31-3*level)*1000/60;
            if(gameover){
                msg.append("\t\t(GAME OVER)");
            }
            label->setText(msg);
            update = false;
        }
        restartTime();
    }
}

void Control::restartTime()
{
    timer.stop();
    timer.start();
}

void Control::readSlotGames()
{
    FILE* arq = fopen("./game.sgf", "r+");
    if(arq){
        int n;
        int x, y;
        int l, s;
        char* linha = (char*) malloc(100);
        QVector<Game*> games;
        QDate date;
        fscanf(arq,"%[^\n]%*c\n", linha); // Snake Game - Version 0.1
        for(int i=0; i<5; i++){
            fscanf(arq,"%[^\n]%*c\n", linha);
            player.clear();
            player.append(linha);
            fscanf(arq,"%[^\n]%*c\n", linha);
            date = QDate::fromString(linha, "dd/MM/yyyy");
            fscanf(arq,"%i\n", &l);
            fscanf(arq,"%i\n", &scores);
            fscanf(arq,"%i %i\n", &x, &y);
            QPoint e(x, y);
            fscanf(arq,"%i\n", &n);
            QVector<QPoint> body;
            body.resize(n);
            for(int i=0; i<n; i++){
                fscanf(arq,"%i %i\n", &x, &y);
                body[i] = QPoint(x,y);
            }
            Game* g = new Game();
            g->setup(player, cellLenght, grid_x, grid_y);
            g->setData(player, l, s, date);
            g->start();
            g->restartGame(l, s, body, e);
            games.append(g);
        }
        fclose(arq);
    }
    else{
        qDebug() << "No SGF";
    }
}
